package com.zhiche.lisa.bms.service.bill.impl;

import com.google.common.collect.Lists;
import com.zhiche.lisa.bms.controller.bill.BillIoController;
import com.zhiche.lisa.bms.dao.model.bill.Bill;
import com.zhiche.lisa.bms.dao.model.bill.BillIo;
import com.zhiche.lisa.bms.dao.model.bill.BillIoDetail;
import com.zhiche.lisa.bms.dao.model.fee.FeeReceivable;
import com.zhiche.lisa.bms.pojo.dto.bill.BillIoDTO;
import com.zhiche.lisa.bms.pojo.dto.util.LspBasicDTO;
import com.zhiche.lisa.bms.pojo.dto.util.LspFleetDTO;
import com.zhiche.lisa.bms.service.bill.BillIoDetailService;
import com.zhiche.lisa.bms.service.bill.BillIoService;
import com.zhiche.lisa.bms.service.bill.BillService;
import com.zhiche.lisa.bms.service.bill.BillSynchroService;
import com.zhiche.lisa.bms.service.fee.FeeReceivableService;
import com.zhiche.lisa.bms.service.utils.LspUtil;
import com.zhiche.lisa.bms.service.utils.UaaUtil;
import com.zhiche.lisa.core.supports.BaseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Author: WangShuiJin
 * @Description:
 * @Date: Create in 10:15 2018/9/10
 */
@Service
public class BillSynchroServiceImpl implements BillSynchroService {
	private static final Logger LOGGER = LoggerFactory.getLogger(BillIoController.class);

	/**
	 * 中联物流（中国）有限公司,ID标识
	 */
	private final Long UNLCN_LOGISTICS_ID = 1L;
	/**
	 * 中联物流（中国）有限公司,名称标识
	 */
	private final String UNLCN_LOGISTICS_NAME = "中联物流（中国）有限公司";

	/**
	 * 账单版本(默认为1)
	 */
	private final Long BILL_VERSION = 1L;

	@Autowired
	private BillIoDetailService billIoDetailService;
	@Autowired
	private BillIoService billIoService;
	@Autowired
	private BillService billService;
	@Autowired
	private UaaUtil uaaUtil;
	@Autowired
	private LspUtil lspUtil;
	@Autowired
	private FeeReceivableService feeReceivableService;

	/**
	 * 账单同步
	 *
	 * @param billIoDTO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void synchroBillData(BillIoDTO billIoDTO) {
		if (Objects.isNull(billIoDTO)) {
			throw new BaseException("账单数据同步失败！");
		}
		//根据收款方ID[承运商ID]，得到承运商表
		LspBasicDTO lspBasicDTO = lspUtil.getLspById(billIoDTO.getPayeeId());
		if (Objects.isNull(lspBasicDTO) && Objects.isNull(lspBasicDTO.getName())) {
			throw new BaseException("获取承运商数据，失败！");
		}
		//对BillIoDTO进行赋值处理
		billIoDTO = this.setBillIoDTO(billIoDTO, lspBasicDTO);
		//向客户或承运商【账单表】插入数据
		Long id = billIoService.insertBillIo(billIoDTO);
		//拿到多条，账单明细数据
		List<BillIoDetail> billIoDetailList = billIoDTO.getBillIoDetailList();
		if (!CollectionUtils.isEmpty(billIoDetailList)) {
			billIoDetailList.forEach(billIoDtl -> {
				if (Objects.isNull(billIoDtl.getActPrice()) && Objects.isNull(billIoDtl.getKilometre())
						&& Objects.nonNull(billIoDtl.getActualAmt())) {
					billIoDtl.setActualPrice(billIoDtl.getActualAmt());
					billIoDtl.setKilometre(BigDecimal.ONE);
				}
			});
		}
		//向客户或承运商【账单明细表】插入数据
		billIoDetailService.insertBillIoDetail(billIoDetailList, id);
		//得到新增后，应收账款的主键
		List<Long> longs = this.insertFeeReceivable(billIoDetailList, billIoDTO, lspBasicDTO);

		//向账单表插入数据
		Bill billObj = new Bill();
		BeanUtils.copyProperties(billIoDTO, billObj);
		//账单表对应的账单类型：应收账单(AR)=20 ， 应付账单(AP)=10
		if (BillIoServiceImpl.INCOME_BILL.equals(billIoDTO.getBillType())) {//AR
			billObj.setBillType("20");
		} else if (BillIoServiceImpl.PAYMENT_BILL.equals(billIoDTO.getBillType())) {//AP
			billObj.setBillType("10");
		}
		billObj.setCustomerBillId(id);
		billObj.setCustomerBillCode(billIoDTO.getBillCode());
		billService.insertBillAndDetail(billObj, longs);
	}

	/**
	 * 对BillIoDTO进行赋值处理
	 *
	 * @param billIoDTO   客户或承运商【账单表】
	 * @param lspBasicDTO 承运商表
	 * @return 赋值后的BillIoDTO
	 */
	private BillIoDTO setBillIoDTO(BillIoDTO billIoDTO, LspBasicDTO lspBasicDTO) {
		//避免数据库is_delete字段为null
		billIoDTO.setIsDelete(0);
		//收款方名称
		billIoDTO.setPayeeName(lspBasicDTO.getName());
		//付款方中联物流，ID默认为1，
		billIoDTO.setPayerId(UNLCN_LOGISTICS_ID);
		//付款方名称
		billIoDTO.setPayerName(UNLCN_LOGISTICS_NAME);
		//租户ID
		billIoDTO.setTenantId(lspBasicDTO.getTenantId());
		//出账时间（既同步时间）.
		billIoDTO.setPublishTime(new Date());
		//得到一个最新的版本号
		Long billVersion = this.versionUpgrade(billIoDTO);
		//账单版本
		billIoDTO.setBillVersion(billVersion);
		//账单状态：10-未对账 20-已出账, 30-已确认, 40-已结算, 50-已取消
		billIoDTO.setBillStatus("10");
		//客户是否确认；0-否 1-是 2-取消
		billIoDTO.setIsAffirm(0);
		//车队名称
		LspFleetDTO fleetInfo = lspUtil.getFleetInfo(billIoDTO.getFleetId());
		if (null != fleetInfo && !ObjectUtils.isEmpty(fleetInfo.getFleetName())) {
			billIoDTO.setFleetName(fleetInfo.getFleetName());
		}
		return billIoDTO;
	}

	/**
	 * 版本更新
	 *
	 * @param billIoDTO
	 * @return
	 */
	@Override
	public Long versionUpgrade(BillIoDTO billIoDTO) {
		Long billVersion = BILL_VERSION;
		BillIo billIoData = billIoService.getBillIoByTypeAndCode(billIoDTO.getBillCode(), billIoDTO.getBillType());
		//如果账单编号存在则进行版本升级
		if (!ObjectUtils.isEmpty(billIoData)) {
			//拿到数据库账单编号对应的版本号
			Long version = billIoData.getBillVersion();
			//执行逻辑删除
			billIoService.deleteBillIo(billIoData.getBillCode(), billIoData.getBillType());
			//升级一个版本
			billVersion = ++version;
		}
		return billVersion;
	}

	/**
	 * 调用新增应收账款接口
	 *
	 * @param billIoDetailList 账单明细数据
	 * @param billIoDTO        //账单数据
	 * @param lspBasicDTO      //承运商数据
	 * @return 新增后的主键
	 */
	private List<Long> insertFeeReceivable(List<BillIoDetail> billIoDetailList, BillIoDTO billIoDTO, LspBasicDTO lspBasicDTO) {
		//筛选数据给FeeReceivable实体类
		List<FeeReceivable> lisaFeeReceivableList = Lists.newArrayList();
		billIoDetailList.forEach(billIoDetailObj -> {
			FeeReceivable feeReceivable = new FeeReceivable();
			//账单表
			feeReceivable.setTenantId(lspBasicDTO.getTenantId());//租户ID
			feeReceivable.setReceiptDate(billIoDTO.getReceiptDate());//回单时间
			feeReceivable.setPayerId(Long.valueOf(billIoDTO.getPayerId()));//付款方ID
			feeReceivable.setPayeeId(Long.valueOf(billIoDTO.getPayeeId()));//收款方ID

			//账单明细表 [ship_code = waybill_id , ship_dtl_code = waybill_dtl_id]
			feeReceivable.setWaybillId(billIoDetailObj.getShipCode());//主运单表码
			feeReceivable.setWaybillDtlId(billIoDetailObj.getShipCode());//主运单表码
//            feeReceivable.setWaybillDtlId(billIoDetailObj.getShipDtlId());
			feeReceivable.setWaybillDtlId(billIoDetailObj.getShipCode());//运单明细编码（目前主运单表码和运单明细编码是一样的）
			feeReceivable.setStartAddr(billIoDetailObj.getStartAddr());//起运地
			feeReceivable.setEndAddr(billIoDetailObj.getEndAddr());//目的地
			feeReceivable.setVehicleTypeName(billIoDetailObj.getVehicleTypeName());//车型名称
			//主系統推送的标识0-已发运 1-已运抵 2-已回单，转换处理
			if ("0".equals(billIoDetailObj.getLoadStatus())) {
				feeReceivable.setLoadStatus("10");//已发运
			} else if ("1".equals(billIoDetailObj.getLoadStatus())) {
				feeReceivable.setLoadStatus("20");//已运抵
			} else if ("2".equals(billIoDetailObj.getLoadStatus())) {
				feeReceivable.setLoadStatus("30");//已回单
			}
			// 运输方式
			feeReceivable.setTransModel(billIoDetailObj.getTransModel());
			// 客户运单号
			feeReceivable.setCusWaybill(billIoDetailObj.getCustomerCode());
			lisaFeeReceivableList.add(feeReceivable);
		});
		//得到收款方ID[承运商ID]对应的租户ID
		Long tenantId = lspBasicDTO.getTenantId();
		//根据租户ID，模拟登录拿到Token
		String tenantToken = uaaUtil.getTenantToken(String.valueOf(tenantId));
		if (!StringUtils.hasText(tenantToken)) {
			throw new BaseException("通过租户ID,模拟登录拿Token，失败！");
		}
		//新增应收账
		List<Long> longs = feeReceivableService.insertFeeReceivablebms(lisaFeeReceivableList, tenantToken);
		return longs;
	}
}
